import struct
from datetime import datetime, timezone, timedelta
from src import device_heartbeat,Master_ip_data,Node_raw_data
from src import WR_config,Device_config
from epics import caput 
def Master_HeartBeat(data):
    if len(data) != 18:
        print(f"Invalid heartbeat packet length: {len(data)}")
        return None
    identifier, reserved, Sync_status, reserved, crc = struct.unpack('!4s B B 10s H', data)
    # print(identifier, reserved, Sync_status, reserved, crc)
    return Sync_status
def Node_HeartBeat(data):
    if len(data) != 18:
        print(f"Invalid heartbeat packet length: {len(data)}")
        return None
    identifier, wr_device_no, device_group, ready_signal, reserved, crc = struct.unpack('!2s I B B 8s H', data)
    # print(identifier, wr_device_no, device_group, ready_signal, reserved, crc)
    return ready_signal
    
    
def Timestamp_Trans(timestamp):
    timestamp_data = timestamp
    ns_timestamp = (int(timestamp_data[0:3].hex(),16) << 4)+(timestamp_data[3] >> 4) 
    s_timestamp = ((timestamp_data[3] & 15) << 36) +(int(timestamp_data[4:8].hex(),16) << 4) + (timestamp_data[-1] >> 4)
    # 将秒计数和纳秒计数转换为UTC时间
    utc_time = datetime.fromtimestamp(s_timestamp, tz=timezone.utc) + timedelta(microseconds=ns_timestamp *16 / 1000)
    # 格式化为字符串
    utc_time_str = utc_time.isoformat()
    return {"s":s_timestamp,"ns":ns_timestamp,"UTC": utc_time_str}

def parse_lock_loss_timestamp_packet(data):
    if len(data) != 18:
        print(f"Invalid lock loss timestamp packet length: {len(data)}")
        return None
    identifier, device_no, timestamp, reserved, crc = struct.unpack('!2s I 9s s H', data)
    # print(identifier, device_no, timestamp, reserved, crc)
    return Timestamp_Trans(timestamp)

def parse_interlock_packet(data):
    if len(data) != 18:
        print(f"Invalid interlock packet length: {len(data)}")
        return None
    identifier, wr_device_no, interlock_status, reserved, crc = struct.unpack('!2s I H 8s H', data)
    # print(identifier, wr_device_no, interlock_status, reserved, crc)
    return interlock_status

master_SyncStatus = {}
pvname_data = {}
for pvname,host in Node_raw_data.items():
    pvname_data[host] = pvname                                                              
def parse_udp_packet(ip,data):
    # 心跳包
    if data[:2] == b'\x48\x42':
        ready_signal = Node_HeartBeat(data)
        device_heartbeat.ready_signal(ip,ready_signal)
    # Master心跳包
    elif data[:4] == b"\x4d\x41\x53\x54":
        if ip in Master_ip_data.values():
            Sync_status = Master_HeartBeat(data)
            master_SyncStatus[ip] = Sync_status
        if 0 in list(master_SyncStatus.values()):
            a = caput(WR_config["Master同步状态"],0)
            # print(master_SyncStatus)
        else:
            a = caput(WR_config["Master同步状态"],1)
    # 联锁包
    elif data[:2] == b"\x49\x4c":
        print(data)
        if ip in pvname_data.keys():
            interlock_status = parse_interlock_packet(data)
            if interlock_status == 1:
                a = caput(Device_config["联锁状态"].format(pvname_data[ip]),1)
            elif interlock_status == 0: 
                a = caput(Device_config["联锁状态"].format(pvname_data[ip]),0)
                a = caput(Device_config["联锁锁存状态"].format(pvname_data[ip]),0)
    # 联锁时间戳包
    elif data[:2] == b"\x54\x4d":
        timestamp = parse_lock_loss_timestamp_packet(data)
        # print(Device_config["联锁时间戳"].format(pvname_data[ip]),timestamp)
        a = caput(Device_config["联锁时间戳"].format(pvname_data[ip]),timestamp["UTC"])